package com.damon.thread;

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Types;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.damon.entity.ApiEntity;
import com.damon.log.WcsLog;
import com.damon.utils.DbUtil;
import com.damon.utils.GlobalOjbectUtil;
import com.damon.utils.HttpResponse;
import com.damon.utils.HttpUtils;
import com.damon.utils.LogUtil;
import com.damon.utils.PropertiesUtil;
import com.damon.utils.ThreadPoolUtil;

import ch.qos.logback.core.util.FileUtil;

public class ApiThread extends Thread{
	private static WcsLog staticLogger = LogUtil.getLogger(ApiThread.class);
	static private String imgRegex ;
	static private String noPostRegex ;
	static private String imgSeparator ;
	static private int barcodeIndex ;
	static private int timestampIndex ;
	static private String imgSuffix ;
	static private String imgTempDir ;
	
	static {
		try {
			imgRegex = PropertiesUtil.propertiesMap.get("IMG_REGEX");
			noPostRegex = PropertiesUtil.propertiesMap.get("NOT_POST_REGEX");
			imgSeparator = PropertiesUtil.propertiesMap.get("IMG_SEPARATOR");
			barcodeIndex = Integer.parseInt(PropertiesUtil.propertiesMap.get("BARCODE_INDEX"));
			timestampIndex = Integer.parseInt(PropertiesUtil.propertiesMap.get("TIMESTAMP_INDEX"));
			imgSuffix = PropertiesUtil.propertiesMap.get("IMG_SUFFIX");
			imgTempDir = PropertiesUtil.propertiesMap.get("IMG_TMEP_DIR");
		} catch (NumberFormatException e) {
			staticLogger.error("数字转换异常，下标应只填数字！！",e);
		} catch (Exception e) {
			staticLogger.error("配置文件填写错误，重新检查配置文件！！");
		}
		
	}
	
	private WcsLog logger;
	ApiEntity apiInfo;
	long start = 0;
	File file = null;//具体发送的图片
//	String responseMsg = null;
	File imgFilse = null;
	
	
	public ApiThread(ApiEntity apiEntity) {
		this.apiInfo = apiEntity;
		this.logger = LogUtil.getLogger(ApiThread.class, apiInfo);
		this.imgFilse = new File(apiEntity.getFilePath());
	}
	public ApiThread(ApiEntity apiEntity,String threadName) {
		this.apiInfo = apiEntity;
		this.logger = LogUtil.getLogger(ApiThread.class, apiInfo);
		this.imgFilse = new File(apiEntity.getFilePath());
		this.setName(threadName);
	}
	
	@Override
	public void run() {
//		String url = apiInfo.getUrl();//调用的api地址
		int time = apiInfo.getBlockingTime();//循环扫描间隔
		String apiName = apiInfo.getConfigDesc();//api描述信息
		
		String apiPrintInfo = "["+apiName+"]-"+"[扫描路径："+apiInfo.getFilePath()+"]-"+"["+apiInfo.getUrl()+"]";
		logger.info("Api："+apiPrintInfo+"创建线程成功！");
		//添加到已监控url表
		GlobalOjbectUtil.getLiveApiThreadSet().add(apiPrintInfo);
		GlobalOjbectUtil.getWindow().getDeviceStatusLabel()
						.setText("已监控Api数："+GlobalOjbectUtil.getLiveApiThreadSet().size());
		
		
		while(true) {
			try {
//				logger.info(Thread.currentThread().getState().toString());
				//扫描文件夹
				traverseAllImg();
			} catch (UnsupportedEncodingException e) {
				logger.error("添加json参数失败", e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			} 
			catch (IOException e) {
				logger.error("io流异常",e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			} 
			catch (Exception e) {
				logger.error("未知错误："+e.getMessage(),e);
				e.printStackTrace();
				logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
			}
//			扫描间隔时间时间：根据表中配置
			try {
				Thread.sleep(time);
			} catch (InterruptedException e) {
				logger.error("线程阻塞sleep方法产生错误！",e);
				e.printStackTrace();
			}
		}
	}
	/**
	 * 改方法会遍历一次文件夹，将所有扫描到的文件做一次处理。
	 * 当一次扫描未完成时
	 * 符合条码格式的，正确上传京东。
	 * 不符合条码格式的直接删除。
	 * @throws IOException
	 */
	public void traverseAllImg() throws IOException {
	   
	    File rootFile=imgFilse;//该线程的根目录，对应一个扫码器。
	    if(rootFile.exists() && rootFile.isDirectory()){
	        LinkedList<File> list=new LinkedList<File>();//存放需要被进行遍历的文件夹，只存放文件夹
	        list.add(rootFile);
	        //当所有文件夹为空时跳出循环
	        while(!list.isEmpty()){
	            File currentDir=list.removeFirst();
	            File[] currentDirList=currentDir.listFiles();//当前被遍历的文件夹下的list
	            for(File currentFile:currentDirList){
	            	//遍历到文件夹时，处理文件夹
	                if(currentFile.exists()&&currentFile.isDirectory()){
	                	
	                    if(currentFile.listFiles().length==0) {
	                    	//文件夹为空,不做处理，删除空文件的逻辑太过繁琐，对业务响应不大，暂不做处理。
//	                    	currentFile.lastModified();
//	                    	FileUtils.deleteDirectory(f);
	                    }else {
	                    	//文件夹不为空,添加到待遍历列表
	                    	list.add(currentFile);
	                    }
	                    
	                }else if(currentFile.exists()&&currentFile.isFile()){
	                	try {
							Thread.sleep(50);
						} catch (InterruptedException e1) {
							e1.printStackTrace();
						}
	                	//遍历到文件时，处理图片
	                	File newFile = null;
	                    start = System.currentTimeMillis();
	                	try {
	                		
	                		//进行格式检查,如果格式错误直接删除
	                		//UG_JD0032822199259-1-1-_20210429162355630_QJ_1619684635630_GR
	                		boolean checkResult = currentFile.getName().matches(imgRegex);
	                		//进行格式检查，如果符合该格式，直接删除
	                		boolean checkResult2 = currentFile.getName().matches(noPostRegex);
	                		
	                		if(checkResult == false || checkResult2==true) {
	                			if(currentFile!=null) {
	                				currentFile.delete();
		                			synchronized (WcsLog.class) {
		                				logger.info("该条码无需上传："+currentFile.getName()+",已删除！！");
										logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
		                			}
	                			}
	                			continue;
	                		}
	                		//从图片格式中提取条码和时间戳，并拼接京东需要的文件格式
		                    String[] allNames = currentFile.getName().replaceFirst(".jpg", "").split(imgSeparator);
		                    String operateTime = allNames[timestampIndex];
		                    String barcode = allNames[barcodeIndex];
		                    
		                    
		                     //将文件复制成京东需要的文件格式
		                    File newFileDir = new File(imgTempDir+File.separator+Thread.currentThread().getName());
		                    if(newFileDir.exists()&&newFileDir.isDirectory()) {
		                    	newFile = new File(newFileDir+File.separator+barcode+imgSuffix);
		                    }else {
		                    	newFileDir.mkdirs();
		                    	newFile = new File(newFileDir+File.separator+barcode+imgSuffix);
		                    }
		                    currentFile.renameTo(newFile);
		                    //使用线程池异步发送post请求
		                    ThreadPoolUtil.getExecutor().execute(new PostThread(currentFile, newFile, apiInfo, operateTime,start));
		                    
//		                    //发送图片个京东
//		                    String responseMsg = sendImg(newFile,operateTime);
//		    				//执行图片删除逻辑
//							if( newFile !=null && newFile.isFile()) {
//								newFile.delete();
//								synchronized (WcsLog.class) {
//									logger.info("key-value参数：machineCode-"+apiInfo.getMachineCode()+"&siteCode-"+apiInfo.getSiteCode()+"&operateTime-"+operateTime);
//									logger.info("响应信息："+responseMsg);
//									if(!"请求失败".equals(responseMsg)) {
//										if( currentFile !=null && currentFile.isFile()) {
//											currentFile.delete();
//										}
//										logger.info("图片["+currentFile.getName()+"]已删除！");
//										logger.info("图片["+newFile.getName()+"]已上传！");
//									}else {
//										logger.info("图片["+currentFile.getName()+"]保留,待下次上传！");
//									}
//									logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
//								}
//							}
						} catch (RuntimeException e) {
							//出现运行时异常时首先保证图片能被删除。
							if( currentFile !=null && currentFile.isFile() && currentFile.exists()) {
								currentFile.delete();
							}
							if( newFile !=null && newFile.isFile() && newFile.exists()) {
								newFile.delete();
							}
							synchronized (WcsLog.class) {
								logger.error("产生运行时异常。。",e);
								logger.error("出现异常，删除图片！！");
								logger.info("用时："+(System.currentTimeMillis()-start)+"ms!!\n");
							}
							
						}
	                 
	                }else {
	                	logger.info("文件已不存在！！");
	                }
	            }
	        }
	        
	    }else{
	    	rootFile.mkdirs();
	        logger.info("文件目录不存在,已创建！");
	       
	    }
	
		
	}
	
	/**
	 * 发送http请求
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public String sendImg(File file,String operateTime) throws IOException {
        // keyValues 保存普通参数
        Map<String, Object> keyValues = new HashMap<>();
        keyValues.put("machineCode", apiInfo.getMachineCode());
        keyValues.put("siteCode", apiInfo.getSiteCode());
        keyValues.put("operateTime", operateTime);
        
        // filePathMap 保存文件类型的参数名和文件路径
        Map<String, String> filePathMap = new HashMap<>();
        String paramName = "image";
        filePathMap.put(paramName, file.getPath());

        //headers
        Map<String, Object> headers = new HashMap<>();

        //发送post请求
        String responseMsg = HttpUtils.postFormData(apiInfo.getUrl(), filePathMap, keyValues, headers);
        return responseMsg;
	}
}
